package com.szy.bigevent.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.szy.bigevent.annotions.Log;
import com.szy.bigevent.mapper.SysOperLogMapper;
import com.szy.bigevent.pojo.SysOperLog;
import com.szy.bigevent.utils.IpUtil;
import com.szy.bigevent.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Map;

@Aspect
@Component
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private SysOperLogMapper sysOperLogMapper;

    private static final ThreadLocal<Long> TIME_THREAD_LOCAL
            = new NamedThreadLocal<>("Cost Time");

    @Pointcut(value = "@annotation(log)", argNames = "log")
    public void pointcut(Log log){}

    @Before(value = "pointcut(log)")
    public void before(Log log){
        TIME_THREAD_LOCAL.set(System.currentTimeMillis());
    }


    @After(value = "pointcut(log)")
    public void afterLogWrite(JoinPoint joinPoint, Log log){
        // 创建日志对象
        SysOperLog sysOperLog = new SysOperLog();
        // 获取调用的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 获取我们调用的类的名称
        String className = joinPoint.getTarget().getClass().getName();
        // 方法名称
        String methodName = method.getName();
        // 方法 全路径
        methodName = className+ "." + methodName;

        // 获取方法的参数
        Object[] args = joinPoint.getArgs();
        ObjectMapper objectMapper = new ObjectMapper();
        String params = "";
        try {
            params =  objectMapper.writeValueAsString(args);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // 获取注解中的操作名称
        String operation = log.operation();
        // 获取注解中的操作类型
        String businessType = log.businessType().toString();

        //获取用户名:注册及登录业务无用户
        String username = "";
        Map<String,Object> map = ThreadLocalUtil.get();
        if (map != null && !map.isEmpty()){
            username = (String) map.get("username");
        }
        else {
            username = (String) args[0];
        }

        // 获取ip地址
        String ipAddress = IpUtil.getIpAddr(request);

        sysOperLog.setBusinessType(businessType);
        sysOperLog.setOperation(operation);
        sysOperLog.setMethod(methodName);
        sysOperLog.setParams(params);
        sysOperLog.setIp(ipAddress);
        sysOperLog.setOperName(username);
        sysOperLog.setCreateTime(LocalDateTime.now());

        sysOperLogMapper.insertSelective(sysOperLog);
    }

}
